package org.zjx.manager;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.zjx.action.IAction;
import org.zjx.core.IWindow;

import java.util.concurrent.*;

/**
 * 激活命令执行器 - 串行同步执行，避免多线程冲突
 */
@Slf4j
public class ActivationManager {
    private static final BlockingQueue<ActivationTask> actionQueue = new LinkedBlockingQueue<>();
    private static final ExecutorService executor = Executors.newSingleThreadExecutor(r -> {
        Thread t = new Thread(r, "ActivationManager");
        t.setDaemon(true);
        return t;
    });

    private static volatile boolean running = true;
    /**
     * -- GETTER --
     *  获取当前激活的窗口
     */
    @Getter
    private static IWindow currentActiveWindow = null;

    static {
        startProcessor();
    }

    private ActivationManager() {}

    /**
     * 同步执行需要激活权的命令
     */
    public static void executeWithActivation(IAction action) throws InterruptedException {
        if (action == null) {
            throw new IllegalArgumentException("命令不能为空");
        }

        // 检查中断状态
        if (Thread.currentThread().isInterrupted()) {
            throw new InterruptedException("线程已被中断");
        }

        CompletableFuture<Boolean> future = new CompletableFuture<>();
        ActivationTask task = new ActivationTask(action, future);

        log.debug("[激活] 提交命令: {}", action.getActionName());

        // 提交到队列
        if (!actionQueue.offer(task)) {
            throw new RuntimeException("激活队列已满");
        }

        try {
            Boolean result = future.get();
            if (!result) {
                throw new RuntimeException("命令执行失败");
            }
        } catch (ExecutionException e) {
            Throwable cause = e.getCause();
            if (cause instanceof RuntimeException) {
                throw (RuntimeException) cause;
            }
            throw new RuntimeException("命令执行异常", cause);
        } catch (CancellationException e) {
            throw new InterruptedException("命令被取消");
        }
    }

    /**
     * 启动命令处理器
     */
    private static void startProcessor() {
        executor.execute(() -> {
            while (running) {
                try {
                    ActivationTask task = actionQueue.take(); // 使用take而不是poll
                    processTask(task);
                } catch (InterruptedException e) {
                    if (running) {
                        log.warn("[激活] 处理器被中断");
                    }
                    break;
                } catch (Exception e) {
                    log.error("[激活] 处理器异常", e);
                }
            }
        });
        log.info("[激活] 命令处理器已启动");
    }

    /**
     * 处理单个任务
     */
    private static void processTask(ActivationTask task) {
        IAction action = task.action;
        IWindow window = action.getTargetWindow();

        log.debug("[激活] 开始执行: {}", action.getActionName());

        try {
            // 检查窗口有效性
            if (!window.isExists()) {
                throw new RuntimeException("窗口已失效: " + window.getTitle());
            }

            // 激活窗口
            activateWindow(window);

            // 执行命令
            boolean success = action.execute();
            task.future.complete(success);

            log.debug("[激活] 执行完成: {}", action.getActionName());

            //释放窗口
            currentActiveWindow = null;

        } catch (InterruptedException e) {
            log.warn("[激活] 命令被中断: {}", action.getActionName());
            task.future.completeExceptionally(e);
            Thread.currentThread().interrupt();
        } catch (Exception e) {
            log.error("[激活] 执行失败: {}", action.getActionName(), e);
            // 发生异常时重置激活状态
            currentActiveWindow = null;
            task.future.completeExceptionally(e);
        }
    }

    /**
     * 激活窗口
     */
    private static void activateWindow(IWindow window) {
        // 如果已经是当前激活窗口，跳过
        if (window.equals(currentActiveWindow)) {
            return;
        }

        try {
            window.activate();
            currentActiveWindow = window;

            // 等待激活完成
            if (!window.waitForActive(500)) {
                throw new RuntimeException("窗口激活超时: " + window.getTitle());
            }

            log.debug("[激活] 窗口已激活: {}", window.getTitle());
        } catch (Exception e) {
            currentActiveWindow = null;
            throw new RuntimeException("激活窗口失败: " + window.getTitle(), e);
        }
    }

    /**
     * 停止处理器
     */
    public static void shutdown() {
        running = false;
        executor.shutdownNow();

        // 清空队列并取消所有待处理任务
        actionQueue.clear();
        log.info("[激活] 已停止");
    }

    /**
     * 检查是否正在处理命令
     */
    public static boolean isProcessing() {
        return !actionQueue.isEmpty() || currentActiveWindow != null;
    }

    /**
     * 激活任务封装
     */
    private static class ActivationTask {
        final IAction action;
        final CompletableFuture<Boolean> future;

        ActivationTask(IAction action, CompletableFuture<Boolean> future) {
            this.action = action;
            this.future = future;
        }
    }
}